﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using TRACv2.Common.Enumerations;
using TRACv2.Domain.DTO;
using TRACv2.Domain.Entities;
using TRACv2.Domain.Services;

//Author:  Morgan William Davis III
//Project: TRAC Ticket Manager v2
//Date: 14 Mar 2014

namespace TRACv2.UI.Facade
{
    public class TRACFacade
    {
        #region [ Fields ]

        private readonly TicketService _ticketService;
        private readonly EmployeeService _employeeService;

        #endregion

        #region [ Constructor ]

        /// <summary>
        /// This is the contructor for the TRACfacade class
        /// </summary>
        /// <param name="ticketService">Needs a ticketService object as a parameter</param>
        /// <param name="employeeService">Needs a employeeService object as a parameter</param>
        public TRACFacade(TicketService ticketService, EmployeeService employeeService)
        {
            _ticketService = ticketService;
            _employeeService = employeeService;
        }

        #endregion

        #region [ Methods ]

        #region [ UI Methods ]

        /// <summary>
        /// Method creates and populates a DataTable for use with DataGridView controls on the forms
        /// </summary>
        /// <returns>A DataTable populated with ticket information</returns>
        public DataTable GetTicketTable(List<TicketDTO> ticketList)
        {
            var gridTable = new DataTable();
            gridTable.Columns.Add("ID", typeof(int));
            gridTable.Columns.Add("Number", typeof(string));
            gridTable.Columns.Add("Date Created", typeof(DateTime));
            gridTable.Columns.Add("Contact", typeof(string));
            gridTable.Columns.Add("Creator", typeof(string));
            gridTable.Columns.Add("Assigned", typeof(string));
            gridTable.Columns.Add("Issue", typeof(string));
            gridTable.Columns.Add("Priority", typeof(string));
            gridTable.Columns.Add("Status", typeof(string));
            gridTable.Columns.Add("Notes", typeof(string));
            foreach (var ticket in ticketList)
            {
                gridTable.Rows.Add(ticket.ID, ticket.Number, ticket.DateCreated, ticket.Contact, ticket.Creator,
                    ticket.Assigned, ticket.Issue, ticket.Priority, ticket.Status, ticket.Note);
            }

            return gridTable;
        }

        /// <summary>
        /// Method is used to return a filtered list of all employees in the database.  
        /// </summary>
        /// <param name="filter">The string that is used as the filter</param>
        /// <returns>Return a list of EmployeeDTO</returns>
        public List<EmployeeDTO> FilterEmployeeList(string filter)
        {
            return _employeeService.GetAll().Where(x => x.ToString().ToUpper().Contains(filter.ToUpper())).ToList();
        }

        #endregion


        #region [ Ticket Service Methods ]

        /// <summary>
        /// Method creates a TicketDTO to be used with other Service Class Methods
        /// </summary>
        /// <param name="contact">employee with the issue</param>
        /// <param name="creator">employee who created the ticket</param>
        /// <param name="assigned">employee assigned to work on the ticket</param>
        /// <param name="issue">the issue the contact is having</param>
        /// <param name="priority">current priority of work assigned to ticket</param>
        /// <param name="status">current status of the resolution of this ticket</param>
        /// <param name="note">any notes pertaining to this ticket</param>
        /// <returns>A single TicketDTO</returns>
        public TicketDTO CreateTicket(int contact, int creator, int assigned, Issue issue, Priority priority, Status status, string note = null)
        {
            var ticket = new TicketDTO
            {
                Contact = contact,
                Creator = creator,
                Assigned = assigned,
                Issue = issue,
                Priority = priority,
                Status = status,
                Note = note
            };

            return ticket;
        }

        /// <summary>
        /// Method calls service object to insert a new ticket into the database
        /// </summary>
        /// <param name="ticket">takes a single TicketDTO as an argument</param>
        public void AddTicket(TicketDTO ticket)
        {
            _ticketService.Add(ticket);
        }

        /// <summary>
        /// Method calls service object to update a ticket that already exists in the database
        /// </summary>
        /// <param name="ticket">takes a single TicketDTO as an argument</param>
        public void UpdateTicket(TicketDTO ticket)
        {
            _ticketService.Update(ticket);
        }

        /// <summary>
        /// Method deletes a ticket from the database
        /// </summary>
        /// <param name="number">takes the target tickets number in the form of a string as an argument</param>
        public void DeleteTicket(TicketDTO ticket)
        {
            _ticketService.Delete(ticket);
        }


        /// <summary>
        /// Method calls service object to move a ticket from the active table to the archived ticket table
        /// </summary>
        /// <param name="ticket">takes a single TicketDTO as an argument</param>
        public void ArchiveTicket(TicketDTO ticket)
        {
            _ticketService.Archive(ticket);
        }


        /// <summary>
        /// Method calls service object to return either a list of all tickets in the database or a filtered list based on different parameters
        /// </summary>
        /// <param name="filter">required parameter, boolean variable that is used to determine if all tickets or a filtered list of tickets is to be returned</param>
        /// <param name="contact">contact argument, optional</param>
        /// <param name="creator">creator argument, optional</param>
        /// <param name="assigned">assigned argument, optional</param>
        /// <param name="issue">issue argument, optional</param>
        /// <param name="priority">priority argument, optional</param>
        /// <param name="status">status argument, optional</param>
        /// <returns>A list collection of TicketDTO</returns>
        public List<TicketDTO> GetAllTickets(bool filter, int? contact = null, int? creator = null, int? assigned = null,
            Issue? issue = null, Priority? priority = null, Status? status = null, DateTime? start = null, DateTime? end = null)
        {
            return _ticketService.GetAll(filter, contact, creator, assigned, issue, priority, status, start, end);
        }

        /// <summary>
        /// Method returns a single TicketDTO based on a specific ticket number
        /// </summary>
        /// <param name="number">the number of the ticket to be returned</param>
        /// <returns>A single TicketDTO</returns>
        public TicketDTO GetTicketByNumber(string number)
        {
            return _ticketService.GetByNumber(number);
        }

        #endregion

        #region [ Employee Service Methods ]


        /// <summary>
        /// Method uses _employeeService to gather all employees in the database into a List collection
        /// </summary>
        /// <returns>Returns a list of EmployeeDTO</returns>
        public List<EmployeeDTO> GetAllEmployees()
        {
            return _employeeService.GetAll();
        }

        /// <summary>
        /// Method uses _employeeService to get a specific employee from the database
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Returns a single EmployeeDTO</returns>
        public EmployeeDTO GetEmployeeByID(int id)
        {
            var employee = _employeeService.GetByID(id);
            return employee;
        }

        #endregion

        #endregion
    }
}
